package correiosNegocios;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import correios.AddressNotFoundException;
import correios.BadCEPInHTMLException;
import correios.BadLatitudeException;
import correios.BadLongitudeException;
import correios.CEPNotFoundException;
import correios.NoAddressInXMLException;
import correios.NoCoordinateInXMLException;
import correios.Utils;
import correiosDados.CEP;
import correiosDados.Coordenada;
import correiosDados.Endereco;
import correiosDados.HTML;

public class IntermediarioGoogleCorreios {

	private static IntermediarioGoogleCorreios me;
	
	public static IntermediarioGoogleCorreios reference(){
		if(me == null){
			me = new IntermediarioGoogleCorreios();
		}
		return me;
	}
	
	public Endereco makeEnderecoRequest(Coordenada coordenada) throws IOException, NoAddressInXMLException{
		
		String xml, aux;
		URL url;
		HttpURLConnection connection;
		String request = new String("http://maps.googleapis.com/maps/api/geocode/xml?latlng=" + coordenada.getLatitude()+"," + coordenada.getLongitude() + "&sensor=false");
		
		url = new URL(request);
		connection = (HttpURLConnection) url.openConnection();
		
		connection.setDoOutput(true); 
	    connection.setInstanceFollowRedirects(false); 
	    
		connection.setRequestMethod("GET");
	    connection.setRequestProperty("Content-Type", "text/plain"); 
	    connection.setRequestProperty("charset", "ISO-8859-1");
	    
		connection.connect();
	    
	    xml = new String();

	    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
	    while ((aux = in.readLine()) != null){
	    	xml = xml.concat(aux);
	    }

	    if(!xml.contains("<formatted_address>")){
	    	throw new NoAddressInXMLException();
	    }
	    return new Endereco(xml.split("<formatted_address>")[1].split("</formatted_address>")[0]);
		
	}
	
	public Endereco makeEnderecoRequest(CEP cep) throws IOException, AddressNotFoundException{
		
		URL url;
		HttpURLConnection connection;
		String request = new String("http://www.buscacep.correios.com.br/servicos/dnec/consultaLogradouroAction.do");
		String parameters = new String("?CEP=" + cep.getValue() + "&Metodo=listaLogradouro&TipoConsulta=cep&StartRow=1&EndRow=10");
		
		HTML content;
		String aux;
		String contentString;
		
		url = new URL(request + parameters);
		connection = (HttpURLConnection) url.openConnection();
		
		connection.setDoOutput(true); 
	    connection.setInstanceFollowRedirects(false); 

	    connection.setRequestMethod("GET");

	    connection.setRequestProperty("Content-Type", "text/plain"); 
	    connection.setRequestProperty("charset", "ISO-8859-1");
	    
		connection.connect();
	    
	    contentString = new String();
	    	
	    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
	    while ((aux = in.readLine()) != null){
	    	contentString = contentString.concat(aux);
	    }
	    
		content = new HTML(contentString);
		
	    return content.parseForEndereco();
	}
	
	public CEP makeCEPRequest(Endereco endereco) throws IOException, CEPNotFoundException, BadCEPInHTMLException{
		
		URL url;
		HttpURLConnection connection;
		String request = new String("http://www.buscacep.correios.com.br/servicos/dnec/consultaEnderecoAction.do");
		String parameters = new String("?relaxation=");
		String [] enderecoChunked;
		
		String aux;
		String contentString;
		
		HTML content;
		
		enderecoChunked = endereco.getValue().split(" ");
		
		for(int i = 0; i < enderecoChunked.length; i++){
			if(Utils.isAlpha(enderecoChunked[i].charAt(0)) || Utils.isDigit(enderecoChunked[i].charAt(0))){
				if(i != 0){
					parameters = parameters.concat("+");
				}
				parameters = parameters.concat(enderecoChunked[i]);
			}
		}
		
		parameters = parameters.concat("&TipoCep=ALL&cfm=1&Metodo=listaLogradouro&TipoConsulta=relaxation&StartRow=1&EndRow=10");
		
		url = new URL(request + parameters);
		connection = (HttpURLConnection) url.openConnection();
		
		connection.setDoOutput(true); 
	    connection.setInstanceFollowRedirects(false); 

	    connection.setRequestMethod("GET");
 
	    connection.setRequestProperty("Content-Type", "text/plain"); 
	    connection.setRequestProperty("charset", "ISO-8859-1");
	    
		connection.connect();
	    
	    contentString = new String();

	    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
	    while ((aux = in.readLine()) != null){
	    	contentString = contentString.concat(aux);
	    }
	    
		content = new HTML(contentString);
	    
	    return content.parseForCEP();
	    
	}
	
	public CEP makeCEPRequest(Coordenada coordenada) throws IOException, CEPNotFoundException, BadCEPInHTMLException, NoAddressInXMLException{
		
		Endereco endereco;
		
		endereco = makeEnderecoRequest(coordenada);
		return makeCEPRequest(endereco);
		
	}
	
	public Coordenada makeCoordenadaRequest(String endereco) throws IOException, BadLatitudeException, BadLongitudeException, NoCoordinateInXMLException{
		String xml, aux;
		URL url;
		HttpURLConnection connection;
		String request;
		double lat, lng;
		
		request = new String("http://maps.googleapis.com/maps/api/geocode/xml?address=" + endereco + "&sensor=false");
		url = new URL(request);
		connection = (HttpURLConnection) url.openConnection();
		
		connection.setDoOutput(true);
	    connection.setInstanceFollowRedirects(false); 
	    
		connection.setRequestMethod("GET");
		
	    connection.setRequestProperty("Content-Type", "text/plain"); 
	    connection.setRequestProperty("charset", "ISO-8859-1");
		connection.connect();
	    
	    xml = new String();
	    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
	    while ((aux = in.readLine()) != null){
	    	xml = xml.concat(aux);
	    }
	    
	    if(!xml.contains("<location>")){
	    	throw new NoCoordinateInXMLException();
	    }
	    xml = xml.split("<location>")[1].split("</location>")[0];
	    lat = Double.valueOf(xml.split("<lat>")[1].split("</lat>")[0]);
	    lng = Double.valueOf(xml.split("<lng>")[1].split("</lng>")[0]);
	    
	    return new Coordenada(lat, lng);
	}
	
}
